package cn.xinfei.xdecision.engine.runner.executor;


import cn.xinfei.xdecision.common.model.component.strategyout.StrategyOutput;
import cn.xinfei.xdecision.common.vo.FieldInfoVo;
import cn.xinfei.xdecision.conf.ApplicationContextUtil;
import cn.xinfei.xdecision.engine.runner.executor.model.StateTransmitModel;
import cn.xinfei.xdecision.engine.runner.executor.strategy.IEngineRunner;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Data
@JsonIgnoreProperties({"handler","iEngineRunner","engineNodeRunner","iengineRunner","nodeHandlerContainer"})
public abstract class AbsNodeHandler<T> {

    public abstract StateTransmitModel handler();

    protected String nodeType;

    protected Map<String, Object> nodeCache = new ConcurrentHashMap();
    /**
     * 组件输入和节点输入
     */
    protected Map<String, FieldInfoVo> inputFields;
    /**
     * 组件输出
     */
    protected Map<String, StrategyOutput> outputFields;
    /**
     * 节点自定义输出
     */
    protected Map<String, StrategyOutput> terminalOutputFields;
    protected NodeHandlerContainer nodeHandlerContainer;
    protected IEngineRunner engineNodeRunner;

    public AbsNodeHandler() {
    }

    public AbsNodeHandler(String nodeType, String handlerType) {
        //组件测试时使用
        this.nodeType = nodeType;
        this.nodeHandlerContainer = ApplicationContextUtil.getBean(NodeHandlerContainer.class);
        this.engineNodeRunner = nodeHandlerContainer.getEngineRunnerNode(nodeType, handlerType);
    }


    public void init() {
        this.engineNodeRunner.before(this);
        this.inputFields = engineNodeRunner.getInputFieldInfo(this);
        this.outputFields = engineNodeRunner.getOutputFieldInfo(this);
        this.terminalOutputFields = engineNodeRunner.getTerminalOutputFieldInfo(this);
    }

    public String getNodeType() {
        return nodeType;
    }


    public <T> T get(String key) {
        T t = (T) nodeCache.get(key);
        return t;
    }

    public void put(String key,Object t) {
        if (key != null && t != null) {
            nodeCache.put(key, t);
        }
    }

    public abstract String getCode();

    public abstract AbsNodeHandler getHandler();

    public abstract void  push();
    public abstract  void pop(StateTransmitModel transmitModel) ;
    /**
     * 记录执行过的节点
     *
     * @param
     */
    public  abstract void  tracer();

    public T next(StateTransmitModel stateTransmitModel) {
        return null;
    }
    public  boolean end(StateTransmitModel stateTransmitModel){
        return true;
    }

}
